package com.service.bean.area;

import com.service.bean.area.Area;
import com.service.bean.point.Point;

public class PolygonArea extends Area {

	@Override
	public boolean isInArea(Point p) {
		int cross = 0;
		Point p1 = null;
		Point p2 = null;
		for (int i = 0; i < points.size(); i++) {
			p1 = points.get(i);
			p2 = points.get((i + 1) % points.size());
			if (p1.baiduLat == p2.baiduLat)
				continue;
			if (p.baiduLat < Math.min(p1.baiduLat, p2.baiduLat))
				continue;
			if (p.baiduLat > Math.max(p1.baiduLat, p2.baiduLat))
				continue;
			if (isPointOnLine(p.baiduLng, p.baiduLat, p1.baiduLng, p1.baiduLat, p2.baiduLng, p2.baiduLat)) {
				// 判断指定点是否在多边形的连线上
				return true;
			}
			double x = (p.baiduLat - p1.baiduLat) * (p2.baiduLng - p1.baiduLng) / (p2.baiduLat - p1.baiduLat) + p1.baiduLng;
			if (x > p.baiduLng)
				cross++;
		}
		return cross % 2 == 1;
	}
	
	public boolean isInArea1(Point p) {
		boolean isInside = false;
		double ESP = 1e-9;
		int count = 0;
		double point1x;
		double point1y;
		double point2x = 180;
		double point2y;
		point1x = p.baiduLng;
		point1y = p.baiduLat;
		point2y = p.baiduLat;
		for (int i = 0; i < this.points.size() - 1; i++) {
			double cx1 = this.points.get(i).baiduLng;
			double cy1 = this.points.get(i).baiduLat;
			double cx2 = this.points.get(i + 1).baiduLng;
			double cy2 = this.points.get(i + 1).baiduLat;
			if (isPointOnLine(point1x, point1y, cx1, cy1, cx2, cy2)) {
				return true;
			}
			if (Math.abs(cy2 - cy1) < ESP) {
				continue;
			}
			if (isPointOnLine(cx1, cy1, point1x, point1y, point2x, point2y)) {
				if (cy1 > cy2)
					count++;
			} else if (isPointOnLine(cx2, cy2, point1x, point1y, point2x,
					point2y)) {
				if (cy2 > cy1)
					count++;
			} else if (isIntersect(cx1, cy1, cx2, cy2, point1x, point1y,
					point2x, point2y)) {
				count++;
			}
		}
		if (count % 2 == 1) {
			isInside = true;
		}
		return isInside;
	}

	private boolean isPointOnLine(double px0, double py0, double px1,
			double py1, double px2, double py2) {
		boolean flag = false;
		double ESP = 1e-9;
		if ((Math.abs(Multiply(px0, py0, px1, py1, px2, py2)) < ESP)
				&& ((px0 - px1) * (px0 - px2) <= 0)
				&& ((py0 - py1) * (py0 - py2) <= 0)) {
			flag = true;
		}
		return flag;
	}

	private double Multiply(double px0, double py0, double px1, double py1,
			double px2, double py2) {
		return ((px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0));
	}

	public boolean isIntersect(double px1, double py1, double px2, double py2,
			double px3, double py3, double px4, double py4) {
		boolean flag = false;
		double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
		if (d != 0) {
			double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3))
					/ d;
			double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1))
					/ d;
			if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1)) {
				flag = true;
			}
		}
		return flag;
	}

}
